<?php
declare(strict_types=1);

namespace App\Controller\Api\V1;

use App\Constant\SmsConstant;
use App\Event\LoginEvent;
use App\Libs\Wechat\WechatService;
use App\Model\User;
use App\Model\UsersLive;
use App\Model\UsersOpenId;
use App\Service\DouService;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\RequestMapping;
use App\Service\UserService;
use App\Service\SmsCodeService;
use Psr\Http\Message\ResponseInterface;
use App\Middleware\JWTAuthMiddleware;
use Hyperf\HttpServer\Annotation\Middleware;

/**
 * 授权相关控制器
 * @Controller(prefix="/api/v1/auth")
 */
class AuthController extends CController
{
    /**
     * @var UserService
     */
    private $userService;

    /**
     * @var DouService
     */
    private $douService;

    /**
     * @var SmsCodeService
     */
    private $sms;

    public function __construct(SmsCodeService $smsCodeService, UserService $userService)
    {
        parent::__construct();

        $this->userService = $userService;
        $this->sms         = $smsCodeService;
    }

    /**
     * 授权登录接口
     *
     * @RequestMapping(path="login", methods="post")
     */
    public function login(): ResponseInterface
    {
        $params = $this->request->inputs(['mobile', 'password', 'platform']);

        $this->validate($params, [
            'mobile'   => "required|phone",
            'password' => 'required',
        ]);

        $user = $this->userService->login($params['mobile'], $params['password']);
        if (!$user) {
            return $this->response->fail('账号不存在或密码填写错误！');
        }
        try {
            $token = $this->guard()->login($user);
        } catch (\Exception $exception) {
            info('登录失败', [$exception->getMessage(), $exception->getFile(), $exception->getLine()]);
            return $this->response->error('登录异常，请稍后再试！');
        }

        event()->dispatch(new LoginEvent($this->request, $user));

        $user = User::find(data_get($user, 'id', ''));
        $r = $user->toArray();
        $r['type'] = 'Bearer';
        $r['access_token'] = $token;
        $r['expires_in'] = $this->guard()->getJwtManager()->getTtl();
        return $this->response->success($r);
    }

    /**
     * 三方授权登录接口
     *
     * @RequestMapping(path="open-login", methods="post")
     */
    public function openLogin(): ResponseInterface
    {
        $params = $this->request->inputs(['token', 'app_id']);

        $this->validate($params, [
            'token'   => "required",
            'app_id' => 'required',
        ]);


        $config = [
            'tt7630008de90e879201' => 'dou',
            'wx154dd8349a505277' => 'wechat',
        ];

        try {

            $s = data_get($config, $params['app_id'], '');
            if ($s == 'dou') {
                $c = new DouService($params['app_id'], env($params['app_id'].'_APP_SECRET'));
                $user = $c->openLogin($params['token']);
            } else {
                $c = new \App\Service\WechatService($params['app_id'], env($params['app_id'].'_APP_SECRET'));
                $user = $c->openLogin($params['token']);
            }


            $user = User::find(data_get($user, 'user_id', ''));
            $userM = $user;
            $token = $this->guard()->login($userM);
        } catch (\Exception $exception) {
            info('登录失败', [$exception->getMessage(), $exception->getFile(), $exception->getLine()]);
            return $this->response->error('登录异常，请稍后再试！');
        }

        event()->dispatch(new LoginEvent($this->request, $userM));

        $r = $user->toArray();
        $r['type'] = 'Bearer';
        $r['access_token'] = $token;
        $r['expires_in'] = $this->guard()->getJwtManager()->getTtl();
        return $this->response->success($r);
    }

    /**
     * @RequestMapping(path="logout", methods="post")
     * @return ResponseInterface
     */
    public function logout(): ResponseInterface
    {
        $this->guard()->check() && $this->guard()->logout();

        return $this->response->success();
    }

    /**
     *
     * @Middleware(JWTAuthMiddleware::class)
     * @RequestMapping(path="me", methods="get")
     * @return ResponseInterface
     */
    public function getMe(): ResponseInterface
    {
        $user_id = $this->uid();

        return $this->response->success(User::select('id', 'name', 'mobile', 'created_at')->find($user_id)->toArray());
    }

    /**
     * 保存用户信息接口
     * @Middleware(JWTAuthMiddleware::class)
     * @RequestMapping(path="save-user", methods="post")
     */
    public function saveUser(): ResponseInterface
    {
        $params = $this->request->inputs(['name', 'head_img']);


        $uid = $this->uid();
        $update = [];
        if (isset($params['name'])) {
            $update['nickname'] = $params['name'];
        }
        if (isset($params['head_img'])) {
            $update['head_img'] = $params['head_img'];
        }

        $u = UsersLive::where('user_id', '=', $uid)
            ->first();

        if (!empty($update)) {
            if (empty($u)) {
                $update['user_id'] = $uid;
                UsersLive::create($update);
            } else {
                UsersLive::where('user_id', '=', $uid)
                    ->update($update);
            }
        }

        return $this->response->success();
    }

    /**
     * 账号注册接口
     *
     * @RequestMapping(path="register", methods="post")
     */
    public function register(): ResponseInterface
    {
        $params = $this->request->all();

        $this->validate($params, [
            'nickname' => "required|max:20",
            'mobile'   => "required|phone",
            'password' => 'required|max:16',
            'sms_code' => 'required|digits:6',
            'platform' => 'required|in:h5,ios,windows,mac,web',
        ]);

        if (!$this->sms->check(SmsConstant::SmsRegisterChannel, (string)$params['mobile'], (string)$params['sms_code'])) {
            return $this->response->fail('验证码填写错误！');
        }

        $isTrue = $this->userService->register([
            'mobile'   => $params['mobile'],
            'password' => $params['password'],
            'nickname' => strip_tags($params['nickname']),
        ]);

        if (!$isTrue) {
            return $this->response->fail('账号注册失败！');
        }

        $this->sms->delCode(SmsConstant::SmsRegisterChannel, $params['mobile']);

        return $this->response->success();
    }

    /**
     * 账号找回接口
     *
     * @RequestMapping(path="forget", methods="post")
     */
    public function forget(): ResponseInterface
    {
        $params = $this->request->inputs(['mobile', 'password', 'sms_code']);

        $this->validate($params, [
            'mobile'   => "required|phone",
            'password' => 'required|max:16',
            'sms_code' => 'required|digits:6',
        ]);

        if (!$this->sms->check(SmsConstant::SmsForgetAccountChannel, (string)$params['mobile'], (string)$params['sms_code'])) {
            return $this->response->fail('验证码填写错误！');
        }

        $isTrue = $this->userService->resetPassword($params['mobile'], $params['password']);
        if (!$isTrue) {
            return $this->response->fail('重置密码失败！');
        }

        $this->sms->delCode(SmsConstant::SmsForgetAccountChannel, $params['mobile']);

        return $this->response->success();
    }

    /**
     * 授权刷新接口
     *
     * @RequestMapping(path="refresh", methods="post")
     */
    public function refresh(): ResponseInterface
    {
        if ($this->guard()->guest()) {
            return $this->response->fail('token 刷新失败！');
        }

        return $this->response->success([
            'type'   => 'Bearer',
            'token'  => $this->guard()->refresh(),
            'expire' => $this->guard()->getJwtManager()->getTtl()
        ]);
    }
}
